package aliyun.cx.admin.security;

import aliyun.cx.admin.util.JwtTokenProvider;
import aliyun.cx.admin.service.UserService;
import aliyun.cx.admin.service.PermissionService;
import aliyun.cx.admin.entity.User;
import aliyun.cx.admin.entity.Permission;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;

/**
 * JWT认证过滤器
 * 拦截请求并验证JWT token，设置Spring Security上下文
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class JwtAuthenticationFilter extends OncePerRequestFilter {

    private final JwtTokenProvider jwtTokenProvider;
    private final UserService userService;
    private final PermissionService permissionService;

    @Override
    protected void doFilterInternal(HttpServletRequest request, 
                                  HttpServletResponse response, 
                                  FilterChain filterChain) throws ServletException, IOException {
        
        try {
            // 从请求头中获取JWT token
            String jwt = getJwtFromRequest(request);
            
            if (StringUtils.hasText(jwt) && jwtTokenProvider.validateToken(jwt)) {
                // 从token中获取用户名和用户ID
                String username = jwtTokenProvider.getUsernameFromToken(jwt);
                Long userId = jwtTokenProvider.getUserIdFromToken(jwt);
                
                // 从数据库中获取用户详细信息
                User user = userService.getById(userId);
                
                if (user != null && user.getEnabled() == 1 && username.equals(user.getUsername())) {
                    // 获取用户权限（这里简化处理，后续可以从数据库查询）
                    List<SimpleGrantedAuthority> authorities = getUserAuthorities(userId);
                    
                    // 创建认证对象
                    UsernamePasswordAuthenticationToken authentication = 
                        new UsernamePasswordAuthenticationToken(user, null, authorities);
                    authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                    
                    // 设置到Spring Security上下文中
                    SecurityContextHolder.getContext().setAuthentication(authentication);
                    
                    log.debug("用户 {} 认证成功", username);
                } else {
                    log.warn("用户 {} 不存在或已禁用", username);
                }
            }
        } catch (Exception ex) {
            log.error("无法设置用户认证: {}", ex.getMessage());
        }
        
        filterChain.doFilter(request, response);
    }

    /**
     * 从请求头中提取JWT token
     */
    private String getJwtFromRequest(HttpServletRequest request) {
        String bearerToken = request.getHeader("Authorization");
        if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) {
            return bearerToken.substring(7);
        }
        return null;
    }

    /**
     * 获取用户权限列表
     * 从数据库中查询用户的实际角色和权限
     */
    private List<SimpleGrantedAuthority> getUserAuthorities(Long userId) {
        try {
            // 获取用户的所有权限
            List<Permission> permissions = permissionService.getPermissionsByUserId(userId);
            
            // 转换为Spring Security的权限格式，使用code字段作为权限标识符
            List<SimpleGrantedAuthority> authorities = permissions.stream()
                .map(permission -> new SimpleGrantedAuthority(permission.getCode()))
                .collect(Collectors.toList());
            
            // 添加默认的USER角色
            authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
            
            return authorities;
        } catch (Exception e) {
            log.error("获取用户权限失败，用户ID: {}", userId, e);
            // 如果获取权限失败，返回最基本的权限
            return List.of(new SimpleGrantedAuthority("ROLE_USER"));
        }
    }

    /**
     * 检查是否应该跳过过滤器
     */
    @Override
    protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
        String path = request.getServletPath();
        
        // 跳过登录、登出等不需要认证的接口
        return path.equals("/api/admin/login") || 
               path.equals("/api/admin/logout") ||
               path.startsWith("/api/upload/images/") ||
               path.startsWith("/actuator/") ||
               path.startsWith("/health") ||
               path.startsWith("/info");
    }
}